\input{../slides/common/slides_common}


\newif\ifbook
\input{../shared/chisel}


\title{Hardware Generators with Chisel}
\author{Martin Schoeberl}
\date{\today}
\institute{Technical University of Denmark}

\begin{document}

\begin{frame}
\titlepage
\end{frame}





\begin{frame}[fragile]{Scala List for Enumeration}
\begin{chisel}
  val empty :: full :: Nil = Enum(2)
\end{chisel}
\begin{itemize}
\item Can be used in wires and registers
\item Symbols for a state machine
\end{itemize}
\end{frame}

\begin{frame}[fragile]{Finite State Machine}
\begin{chisel}
  val empty :: full :: Nil = Enum(2)
  val stateReg = RegInit(empty)
  val dataReg = RegInit(0.U(size.W))

  when(stateReg === empty) {
    when(io.enq.write) {
      stateReg := full
      dataReg := io.enq.din
    }
  }.elsewhen(stateReg === full) {
    when(io.deq.read) {
      stateReg := empty
    }
  }
\end{chisel}
\begin{itemize}
\item A simple buffer for a bubble FIFO
\end{itemize}
\end{frame}

\begin{frame}[fragile]{Parameterization}
\begin{chisel}
class ParamChannel(n: Int) extends Bundle {
  val data = Input(UInt(n.W))
  val ready = Output(Bool())
  val valid = Input(Bool())
}

val ch32 = new ParamChannel(32)
\end{chisel}
\begin{itemize}
\item Bundles and modules can be parametrized
\item Pass a parameter in the constructor
\end{itemize}

\end{frame}
\begin{frame}[fragile]{A Module with a Parameter}
\begin{chisel}
class ParamAdder(n: Int) extends Module {
  val io = IO(new Bundle {
    val a = Input(UInt(n.W))
    val b = Input(UInt(n.W))
    val result = Output(UInt(n.W))
  })

  val addVal = io.a + io.b
  io.result := addVal
}

val add8 = Module(new ParamAdder(8))
\end{chisel}
\begin{itemize}
\item Parameter can also be a Chisel type
\item Can also be a generic type:
\item \code{class Mod[T <: Bits](param: T) extends...}
\end{itemize}
\end{frame}

\begin{frame}[fragile]{Scala \code{for} Loop for Circuit Generation}
\begin{chisel}
val shiftReg = RegInit(0.U(8.W))

shiftReg(0) := inVal

for (i <- 1 until 8) {
  shiftReg(i) := shiftReg(i-1)
}
\end{chisel}
\begin{itemize}
\item \code{for} is Scala
\item This loop generates several connections
\item The connections are parallel hardware
\end{itemize}
\end{frame}

\begin{frame}[fragile]{Conditional Circuit Generation}
\begin{chisel}
class Base extends Module { val io = new Bundle() }
class VariantA extends Base { }
class VariantB extends Base { }

val m = if (useA) Module(new VariantA())
        else Module(new VariantB())
\end{chisel}
\begin{itemize}
\item \code{if} and \code{else} is Scala
\item \code{if} is an expression that returns a value
\begin{itemize}
\item Like ``\code{cond ? a : b;}'' in C and Java
\end{itemize}
\item This is not a hardware multiplexer
\item Decides which module to generate
\item Could even read an XML file for the configuration
\end{itemize}
\end{frame}

% use this for the 4 unit version
\input{generation.tex}

\begin{frame}[fragile]{Combinational (Truth) Table Generation}
\begin{chisel}
val arr = new Array[Bits](length)
for (i <- 0 until length) {
  arr(i) = ...
}
val rom = Vec[Bits](arr)
\end{chisel}
\begin{itemize}
\item Generate a table in a Scala array
\item Use that array as input for a Chisel \code{Vec}
\item Generates a logic table at hardware construction time
\end{itemize}
\end{frame}

\begin{frame}[fragile]{Ideas for Runtime Table Generation}
\begin{itemize}
\item Assembler in Scala/Java generates the boot ROM
\item Table with a \code{sin} function
\item Binary to BCD conversion
\item Schedule table for a TDM based network-on-chip
\item 
\item More ideas?
\end{itemize}
\end{frame}

\begin{frame}[fragile]{Memory}
\begin{chisel}
val mem = Mem(Bits(width = 8), size)

// write
when(wrEna) {
  mem(wrAddr) := wrData
}

// read
val rdAddrReg = Reg(next = rdAddr)
rdData := mem(rdAddrReg)
\end{chisel}
\begin{itemize}
\item Write is synchronous
\item Read can be asynchronous or synchronous
\item But there are no asynchronous memories in an FPGA
\end{itemize}
\end{frame}

\begin{frame}[fragile]{Better Use Synchronous Memory}
\shortlist{../code/memory.txt}
\end{frame}

\begin{frame}[fragile]{Factory Methods}
\begin{itemize}
\item Simpler component creation and use
\item Usage similar to built in components, such as \code{Mux}
\end{itemize}
\begin{chisel}
val myAdder = Adder(x, y)
\end{chisel}
\begin{itemize}
\item A little bit more work on component side
\item Define an \code{apply} method on the companion object that returns the component
\end{itemize}
\begin{chisel}
object Adder {
  def apply(a: UInt, b: UInt) = {
    val adder = Module(new Adder)
    adder.io.a := a
    adder.io.b := b
    adder.io.result
  }
}
\end{chisel}
\end{frame}

\begin{frame}[fragile]{More on Testing}
\begin{itemize}
\item Using test vectors and \code{expect()} does not scale
\item Better have co-simulation against a \emph{golden model}
\item Then we can compare
\item Which input values to use?
\end{itemize}
\end{frame}

\begin{frame}[fragile]{A Tiny ALU: IO Connection}
\begin{chisel}
class Alu extends Module {
  val io = IO(new Bundle {
    val fn = Input(UInt(2.W))
    val a = Input(UInt(4.W))
    val b = Input(UInt(4.W))
    val result = Output(UInt(4.W))
  })

  // Use shorter variable names
  val fn = io.fn
  val a = io.a
  val b = io.b
\end{chisel}
\end{frame}

\begin{frame}[fragile]{A Tiny ALU: The Function}
\begin{chisel}
  val result = Wire(UInt(4.W))
  // some default value is needed
  result := 0.U

  // The ALU selection
  switch(fn) {
    is(0.U) { result := a + b }
    is(1.U) { result := a - b }
    is(2.U) { result := a | b }
    is(3.U) { result := a & b }
  }

  // Output on the LEDs
  io.result := result
}
\end{chisel}
\end{frame}

\begin{frame}[fragile]{Testing the ALU}
\begin{itemize}
\item Compute the expected result in Scala
\end{itemize}
\begin{chisel}
  // This is exhaustive testing,
  // which usually is impossible
  for (a <- 0 to 15) {
    for (b <- 0 to 15) {
      for (op <- 0 to 3) {
        val result =
          op match {
            case 0 => a + b
            case 1 => a - b
            case 2 => a | b
            case 3 => a & b
          }
        val resMask = result & 0x0f
\end{chisel}

\end{frame}

\begin{frame}[fragile]{Testing the ALU}
\begin{itemize}
\item Compare the Scala computed result with the hardware result
\end{itemize}
\begin{chisel}
        poke(dut.io.fn, op)
        poke(dut.io.a, a)
        poke(dut.io.b, b)
        step(1)
        expect(dut.io.result, resMask)
      }
    }
  }
\end{chisel}
\end{frame}


\begin{frame}[fragile]{Printf Debugging}
\begin{itemize}
\item We can \emph{print} in the hardware
\item Printing happens on the rising edge of the clock
\item Good to see many parallel signals and registers
\item \code{printf} anywhere in the module definition
\end{itemize}
\shortlist{../code/test_dut_printf.txt}
\end{frame}


\begin{frame}[fragile]{Test Driven Development (TDD)}
\begin{itemize}
\item Software development process
\begin{itemize}
\item Can we learn from SW development for HW design?
\end{itemize}
\item Writing the test first, then the implementation
\item Started with extreme programming
\begin{itemize}
\item Frequent releases
\item Accept change as part of the development
\end{itemize}
\item A path to \emph{Agile Hardware Development!}
\item Not used in its pour form
\begin{itemize}
\item Writing all those tests is simply considerer too much work
\end{itemize}
\end{itemize}
\end{frame}

\begin{frame}[fragile]{Continuous Integration}
\begin{itemize}
\item Run your tests on each change
\item Do it also when using source control
\item GitHub Actions
\item I am doing it even for the Chisel book
\end{itemize}
\end{frame}

\begin{frame}[fragile]{Testing versus Debugging}
\begin{itemize}
\item Debugging is during code development
\item Waveform and println are easy tools for debugging
\item Debugging does not help for regression tests
\item Write small test cases for regression tests
\item Keeps your code base \emph{intact} when doing changes
\item Better confidence in changes not introducing new bugs
\end{itemize}
\end{frame}



\begin{frame}[fragile]{Summary}
\begin{itemize}
\item Chisel is a small language
\item Embedding it in Scala gives the power
\item We can write circuit generators
\item We can do co-simulation
\item We just scratched the surface
\end{itemize}
\end{frame}

\begin{frame}[fragile]{Links to the Examples}
\begin{itemize}
\item Example code
\end{itemize}
\begin{chisel}
https://github.com/schoeberl/chisel-examples.git
\end{chisel}
\begin{itemize}
\item Slides
\end{itemize}
\begin{chisel}
https://github.com/schoeberl/chisel-book.git
\end{chisel}
\end{frame}

\begin{frame}[fragile]{Feedback}
\begin{itemize}
\item Plans on using Chisel?
\item What went well?
\item What was not so good?
\item How can this Chisel course be improved?
\item
\item Would be happy to receive an email: \code{masca@dtu.dk}
\end{itemize}
\end{frame}

\begin{frame}[fragile]{Simulation Lab Session}
\begin{itemize}
\item Testing Hello World
\item Write test/verification code for a 5:1 multiplexer
\item A more interesting tester on an ALU accumulator
\item Project and DUT in GitHub lab1 and lab2
\item \url{https://github.com/chisel-uvm/class2020}
\end{itemize}
\end{frame}

\begin{frame}[fragile]{FPGA Lab Session}
\begin{itemize}
\item Run and explore the UART (serial port) example
\begin{itemize}
\item There is a make target that builds the UART hardware
\item \code{make uart}
\item It shall write some text out
\item You can observe it with a terminal (e.g., gtkterm)
\end{itemize}
\item Combine the UART with a blinking LED
\begin{itemize}
\item Write a `0' and `1' out on blink off and on
\item Best add the LEDs to \code{UartMain} and \code{uart\_top.vhdl}
\end{itemize}
\item Write repeated numbers 0--9 at maximum speed 
\end{itemize}
\end{frame}

\end{document}

%%%%%%%%%%%%%%%%
\begin{frame}[fragile]{Title}
\begin{chisel}
code
\end{chisel}
\begin{itemize}
\item xxx
\item xxx
\item xxx
\end{itemize}
\end{frame}

\begin{frame}[fragile]{Title}
\begin{itemize}
\item xxx
\item xxx
\item xxx
\item xxx
\item xxx
\end{itemize}
\end{frame}
%%%%%%%%%%%%%%%%

